package com.tao.mvplibrary.utils

import android.os.Handler
import android.os.Looper
import androidx.lifecycle.Lifecycle
import com.uber.autodispose.AutoDispose
import com.uber.autodispose.AutoDisposeConverter
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
import io.reactivex.Flowable
import io.reactivex.FlowableTransformer
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.reactivestreams.Subscriber

object KotRxutils {
    /**
     * 订阅
     *
     * @param observable    被观察者
     * @param observer      观察者
     * @param lifecycle     使用生命周期自动接绑  可为null
     * @param observeOnMain
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Observable<T>, observer: Observer<in T>, lifecycle: Lifecycle?, subscribeOnMain: Boolean, observeOnMain: Boolean) {

        if (lifecycle == null) {

//            getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            if (!subscribeOnMain) {
//                pool.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//                    }
//                });
//            } else {
//                getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            }

            sub(observable, subscribeOnMain, observeOnMain, null, observer)
        } else {
            if (isThreadMain) {
                sub(observable, subscribeOnMain, observeOnMain, lifecycle, observer)
            } else {
                runOnui(Runnable { sub(observable, subscribeOnMain, observeOnMain, lifecycle, observer) })
            }
//            ((ObservableSubscribeProxy) observable.compose(getComposer(subscribeOnMain, observeOnMain)).as(bindLifecycle(lifecycle))).subscribe(observer);
        }
    }

    private fun <T> sub(observable: Observable<T>, subscribeOnMain: Boolean, observeOnMain: Boolean, lifecycle: Lifecycle?, observer: Observer<in T>) {
        val tObservable = observable.subscribeOn(if (subscribeOnMain) AndroidSchedulers.mainThread() else Schedulers.newThread())
                .observeOn(if (observeOnMain) AndroidSchedulers.mainThread() else Schedulers.newThread())
        if (lifecycle != null) {
            tObservable.`as`(bindLifecycle(lifecycle)).subscribe(observer)
        } else {
            tObservable.subscribe(observer)
        }
    }

    /**
     * 绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param lifecycle
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Observable<T>, resultObserver: Observer<T>, lifecycle: Lifecycle?) {
        toSubscribe(observable, resultObserver, lifecycle, false, true)
    }

    fun <T> toSubscribe(observable: Observable<T>, resultObserver: Observer<T>, lifecycle: Lifecycle?, observeOnMain: Boolean) {
        toSubscribe(observable, resultObserver, lifecycle, false, observeOnMain)
    }

    /**
     * 不绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Observable<T>, resultObserver: Observer<T>) {
        toSubscribe(observable, resultObserver, false, true)
    }

    /**
     * 不绑定 生命周期  自由设置观察者线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Observable<T>, resultObserver: Observer<T>, obserMain: Boolean) {
        toSubscribe(observable, resultObserver, false, obserMain)
    }

    fun <T> toSubscribe(observable: Observable<T>, resultObserver: Observer<T>, subscribeOnMain: Boolean, obserMain: Boolean) {
        toSubscribe(observable, resultObserver, null, subscribeOnMain, obserMain)
    }

    /**
     * 是否切换到UI线程
     *
     * @param <T>
     * @param observable
     * @param subscribeOnMain
     * @param observeOnMain
     * @return
    </T> */
    private fun <T> getEntityObservable(observable: Observable<T>, subscribeOnMain: Boolean, observeOnMain: Boolean): Observable<T> {
        if (subscribeOnMain) {
            observable.subscribeOn(AndroidSchedulers.mainThread())
        } else {
            observable.subscribeOn(Schedulers.newThread())
        }
        return if (observeOnMain) observable.observeOn(AndroidSchedulers.mainThread()) else observable.observeOn(Schedulers.newThread())
    }

    /**
     * 订阅
     *
     * @param observable    被观察者
     * @param observer      观察者
     * @param lifecycle     使用生命周期自动接绑  可为null
     * @param observeOnMain
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Flowable<T>, observer: Subscriber<in T>, lifecycle: Lifecycle?, subscribeOnMain: Boolean, observeOnMain: Boolean) {
        if (lifecycle == null) {
//            getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            if (!subscribeOnMain) {
//                pool.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//                    }
//                });
//            } else {
//                getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            }
            sub(observable, subscribeOnMain, observeOnMain, null, observer)
        } else {
            if (isThreadMain) {
                sub(observable, subscribeOnMain, observeOnMain, lifecycle, observer)
            } else {
                runOnui(Runnable { sub(observable, subscribeOnMain, observeOnMain, lifecycle, observer) })
            }

//            ((ObservableSubscribeProxy) observable.compose(getComposer(subscribeOnMain, observeOnMain)).as(bindLifecycle(lifecycle))).subscribe(observer);
        }
    }

    private fun <T> sub(observable: Flowable<T>, subscribeOnMain: Boolean, observeOnMain: Boolean, lifecycle: Lifecycle?, observer: Subscriber<in T>) {
        val tObservable = observable.subscribeOn(if (subscribeOnMain) AndroidSchedulers.mainThread() else Schedulers.newThread())
                .observeOn(if (observeOnMain) AndroidSchedulers.mainThread() else Schedulers.newThread())
        if (lifecycle != null) {
            tObservable.`as`(bindLifecycle(lifecycle)).subscribe(observer)
        } else {
            tObservable.subscribe(observer)
        }
    }

    fun runOnui(runnable: Runnable) {
        Handler(Looper.getMainLooper()).post(runnable)
    }

    /**
     * 绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param lifecycle
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Flowable<T>, resultObserver: Subscriber<T>, lifecycle: Lifecycle?) {
        toSubscribe(observable, resultObserver, lifecycle, false, true)
    }

    fun <T> toSubscribe(observable: Flowable<T>, resultObserver: Subscriber<T>, lifecycle: Lifecycle?, observeOnMain: Boolean) {
        toSubscribe(observable, resultObserver, lifecycle, false, observeOnMain)
    }

    /**
     * 不绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Flowable<T>, resultObserver: Subscriber<T>) {
        toSubscribe(observable, resultObserver, false, true)
    }

    /**
     * 不绑定 生命周期  自由设置观察者线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
    </T> */
    fun <T> toSubscribe(observable: Flowable<T>, resultObserver: Subscriber<T>, obserMain: Boolean) {
        toSubscribe(observable, resultObserver, false, obserMain)
    }

    fun <T> toSubscribe(observable: Flowable<T>, resultObserver: Subscriber<T>, subscribeOnMain: Boolean, obserMain: Boolean) {
        toSubscribe(observable, resultObserver, null, subscribeOnMain, obserMain)
    }

    /**
     * 绑定到lifecycle
     *
     * @param lifecycle
     * @param <T>
     * @return
    </T> */
    fun <T> bindLifecycle(lifecycle: Lifecycle?): AutoDisposeConverter<T> {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycle, Lifecycle.Event.ON_DESTROY))
    }

    /**
     * 线程调度器
     *
     * @param <T>
     * @param subscribeOnMain
     * @param observeOnMain
     * @return
    </T> */
    fun <T> getComposer(subscribeOnMain: Boolean, observeOnMain: Boolean): FlowableTransformer<T, T> {
        return FlowableTransformer { upstream ->
            if (subscribeOnMain) {
                upstream.subscribeOn(AndroidSchedulers.mainThread())
            } else {
                if (isThreadMain) {
                    upstream.subscribeOn(Schedulers.newThread())
                }
            }
            if (observeOnMain) {
                upstream.observeOn(AndroidSchedulers.mainThread())
            } else {
                upstream.observeOn(Schedulers.io())
            }
        }
    }

    private val isThreadMain: Boolean
        private get() = Thread.currentThread().name == Looper.getMainLooper().thread.name

    /**
     * 是否切换到UI线程
     *
     * @param <T>
     * @param observable
     * @param subscribeOnMain
     * @param observeOnMain
     * @return
    </T> */
    private fun <T> getEntityObservable(observable: Flowable<T>, subscribeOnMain: Boolean, observeOnMain: Boolean): Flowable<T> {
        if (subscribeOnMain) {
            observable.subscribeOn(AndroidSchedulers.mainThread())
        } else {
            observable.subscribeOn(Schedulers.newThread())
        }
        return if (observeOnMain) observable.observeOn(AndroidSchedulers.mainThread()) else observable.observeOn(Schedulers.newThread())
    }
}